package com.topvision.myviewtest.gscview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Region;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * @author lucy
 * @date 2018-12-03 17:29
 * @description //TODO
 */

public class ButtonView extends View {
    private Paint mPaint;
    private int mViewWidth;
    private int mViewHeight;
    private Path mPathCenter, mPathUp, mPathDown, mPathLeft, mPathRight;
    private int diffAngle = 1;
    private int mMaxCircleRadius = 500;
    private int mMidCircleRadius = 300;
    private int mMinCircleRadius = 200;
    private Matrix mMatrix;
    public static final int TOUCHED_PATH_CENTER = 0;
    public static final int TOUCHED_PATH_UP = 1;
    public static final int TOUCHED_PATH_DOWN = 2;
    public static final int TOUCHED_PATH_LEFT = 3;
    public static final int TOUCHED_PATH_RIGHT = 4;
    private int mCurrentTouchedPath = -1;
    private int mActionDownPath = -1;
    private OnButtonClickedListener mOnButtonClickedListener;

    public ButtonView(Context context) {
        this(context, null);
    }

    public ButtonView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ButtonView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(Color.BLUE);

        mMatrix = new Matrix();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mMatrix.reset();
        mViewWidth = w;
        mViewHeight = h;

        float bigSweepAngle = 84;
        float smallSweepAngle = -80;
        RectF maxRectF = new RectF(-mMaxCircleRadius, -mMaxCircleRadius, mMaxCircleRadius, mMaxCircleRadius);
        RectF midRectF = new RectF(-mMidCircleRadius, -mMidCircleRadius, mMidCircleRadius, mMidCircleRadius);

        // 中
        mPathCenter = new Path();
        mPathCenter.addCircle(0, 0, mMinCircleRadius, Path.Direction.CW);

        // 上
        mPathUp = new Path();
        mPathUp.addArc(maxRectF, 230, bigSweepAngle);
        mPathUp.arcTo(midRectF, 310, smallSweepAngle);
        mPathUp.close();

        // 左
        mPathLeft = new Path();
        mPathLeft.addArc(maxRectF, 140, bigSweepAngle);
        mPathLeft.arcTo(midRectF, 220, smallSweepAngle);
        mPathLeft.close();

        // 下
        mPathDown = new Path();
        mPathDown.addArc(maxRectF, 50, bigSweepAngle);
        mPathDown.arcTo(midRectF, 130, smallSweepAngle);
        mPathDown.close();

        // 右
        mPathRight = new Path();
        mPathRight.addArc(maxRectF, -40, bigSweepAngle);
        mPathRight.arcTo(midRectF, 40, smallSweepAngle);
        mPathRight.close();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.translate(mViewWidth / 2, mViewHeight / 2);
        // 获取测量矩阵(逆矩阵)
        if (mMatrix.isIdentity()) {
            canvas.getMatrix().invert(mMatrix);
        }
        // 默认 颜色
        mPaint.setColor(Color.BLUE);
        canvas.drawPath(mPathCenter, mPaint);
        canvas.drawPath(mPathUp, mPaint);
        canvas.drawPath(mPathDown, mPaint);
        canvas.drawPath(mPathLeft, mPaint);
        canvas.drawPath(mPathRight, mPaint);
        // 触摸反馈 颜色
        mPaint.setColor(Color.RED);
        if (mCurrentTouchedPath == TOUCHED_PATH_CENTER) {
            canvas.drawPath(mPathCenter, mPaint);
        } else if (mCurrentTouchedPath == TOUCHED_PATH_UP) {
            canvas.drawPath(mPathUp, mPaint);
        } else if (mCurrentTouchedPath == TOUCHED_PATH_RIGHT) {
            canvas.drawPath(mPathRight, mPaint);
        } else if (mCurrentTouchedPath == TOUCHED_PATH_DOWN) {
            canvas.drawPath(mPathDown, mPaint);
        } else if (mCurrentTouchedPath == TOUCHED_PATH_LEFT) {
            canvas.drawPath(mPathLeft, mPaint);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float oldX = event.getRawX();
        float oldY = event.getRawY();
        float[] pts = {oldX, oldY};
        mMatrix.mapPoints(pts);
        int newX = (int) pts[0];
        int newY = (int) pts[1];
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                mActionDownPath = getTouchedPath(newX, newY);
                mCurrentTouchedPath = mActionDownPath;
                break;
            case MotionEvent.ACTION_MOVE:
                mCurrentTouchedPath = getTouchedPath(newX, newY);
                break;
            case MotionEvent.ACTION_UP:
                mCurrentTouchedPath = getTouchedPath(newX, newY);
                // 如果按下和抬起都在一个path判断为点击事件
                if (mActionDownPath == mCurrentTouchedPath && mCurrentTouchedPath != -1 && mOnButtonClickedListener != null) {
                    if (mCurrentTouchedPath == TOUCHED_PATH_CENTER) {
                        mOnButtonClickedListener.onCenterClicked();
                    } else if (mCurrentTouchedPath == TOUCHED_PATH_UP) {
                        mOnButtonClickedListener.onUpClicked();
                    } else if (mCurrentTouchedPath == TOUCHED_PATH_RIGHT) {
                        mOnButtonClickedListener.onRightClicked();
                    } else if (mCurrentTouchedPath == TOUCHED_PATH_DOWN) {
                        mOnButtonClickedListener.onDownClicked();
                    } else if (mCurrentTouchedPath == TOUCHED_PATH_LEFT) {
                        mOnButtonClickedListener.onLeftClicked();
                    }
                }
                // 重置
                mActionDownPath = mCurrentTouchedPath = -1;
                break;
            case MotionEvent.ACTION_CANCEL:
                mActionDownPath = mCurrentTouchedPath = -1;
                break;
            default:
                break;
        }
        invalidate();
        return true;
    }

    private int getTouchedPath(int x, int y) {
        if (pointInPath(mPathCenter,x,y)) {
            return TOUCHED_PATH_CENTER;
        } else if (pointInPath(mPathUp,x,y)) {
            return TOUCHED_PATH_UP;
        } else if (pointInPath(mPathDown,x,y)) {
            return TOUCHED_PATH_DOWN;
        } else if (pointInPath(mPathLeft,x,y)) {
            return TOUCHED_PATH_LEFT;
        } else if (pointInPath(mPathRight,x,y)) {
            return TOUCHED_PATH_RIGHT;
        }
        return -1;
    }

    private boolean pointInPath(Path path, int x, int y) {
        RectF rectF = new RectF();
        path.computeBounds(rectF, true);
        Region region = new Region();
        region.setPath(path, new Region((int) rectF.left, (int) rectF.top, (int) rectF.right, (int) rectF.bottom));
        return region.contains(x, y);
    }

    private void setOnButtonClickedListener(OnButtonClickedListener listener) {
        mOnButtonClickedListener = listener;
    }

    public interface OnButtonClickedListener {
        void onCenterClicked();

        void onUpClicked();

        void onRightClicked();

        void onDownClicked();

        void onLeftClicked();
    }
}
